'use client';

import { useMemo } from 'react';
import useSWR, { mutate as globalMutate } from 'swr';
import { apiClient, EventModel, TaskModel, NotificationModel, MentionModel, AccountModel } from '../lib/api';
import { DEFAULT_OWNER, DEFAULT_ACTOR } from '../lib/config';

type FetcherMap = {
  feed: (owner: string, filter?: string) => Promise<EventModel[]>;
  tasks: (owner: string) => Promise<TaskModel[]>;
  notifications: (owner: string) => Promise<NotificationModel[]>;
  mentions: (owner: string) => Promise<MentionModel[]>;
};

const fetchers: FetcherMap = {
  feed: (owner: string, filter?: string) => apiClient.fetchFeed(owner, filter ? { tags: filter } : {}),
  tasks: (owner: string) => apiClient.fetchTasks(owner),
  notifications: (owner: string) => apiClient.fetchNotifications(owner, owner, 72),
  mentions: (owner: string) => apiClient.fetchMentions(owner, owner)
};

export function useFeed(owner: string = DEFAULT_OWNER, filter?: string) {
  return useSWR<EventModel[]>(['feed', owner, filter], () => fetchers.feed(owner, filter));
}

export function useTasks(owner: string = DEFAULT_OWNER) {
  return useSWR<TaskModel[]>(['tasks', owner], () => fetchers.tasks(owner));
}

export function useNotifications(owner: string = DEFAULT_OWNER) {
  return useSWR<NotificationModel[]>(['notifications', owner], () => fetchers.notifications(owner));
}

export function useMentions(owner: string = DEFAULT_OWNER) {
  return useSWR<MentionModel[]>(['mentions', owner], () => fetchers.mentions(owner));
}

export function useAccounts() {
  return useSWR<AccountModel[]>('accounts', () => apiClient.listAccounts());
}

export function useFeedsForOwners(owners: string[], exclude?: string) {
  const filtered = useMemo(() => {
    return owners
      .filter(Boolean)
      .filter((owner, index, arr) => arr.indexOf(owner) === index)
      .filter(owner => owner !== exclude);
  }, [owners, exclude]);

  return useSWR<EventModel[]>(
    filtered.length ? ['feeds', filtered.sort().join(',')] : null,
    async () => {
      const lists = await Promise.all(filtered.map(owner => apiClient.fetchFeed(owner, { limit: 200 })));
      return lists.flat();
    }
  );
}

export function useActor() {
  return DEFAULT_ACTOR;
}

export function mutateFeed(owner: string = DEFAULT_OWNER) {
  return globalMutate(['feed', owner]);
}

export function mutateTasks(owner: string = DEFAULT_OWNER) {
  return globalMutate(['tasks', owner]);
}

export function mutateAccounts() {
  return globalMutate('accounts');
}
